package org.example.sec10;

import com.google.common.util.concurrent.Uninterruptibles;
import com.seaway.models.sec10.*;
import io.grpc.Context;
import io.grpc.Contexts;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
import org.checkerframework.checker.units.qual.C;
import org.example.sec10.respository.AccountRespository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
public class DeadLineBankService extends BankServiceGrpc.BankServiceImplBase {
    private static final Logger log = LoggerFactory.getLogger(DeadLineBankService.class);

    @Override
    public void getAccountBalance(BalanceCheckRequest request, StreamObserver<AccountBalance> responseObserver) {
        var accountNumber = request.getAccountNumber();
        var balance = AccountRespository.getBalance(accountNumber);
        var accountBalance = AccountBalance.newBuilder().setAccountNumber(accountNumber).setBalance(balance).build();
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        responseObserver.onNext(accountBalance);

        responseObserver.onCompleted();

    }

    @Override
    public void withDraw(WithDrawRequest request, StreamObserver<Money> responseObserver) {
        try {
            int accountNumber = request.getAccountNumber();
            int amount = request.getAmount();
            Integer balance = AccountRespository.getBalance(accountNumber);

            if (amount > balance) {
                responseObserver.onError(Status.FAILED_PRECONDITION.asRuntimeException());
                return;
            }

            for (int i = 0; i < (amount / 10) &&!Context.current().isCancelled(); i++) {
                var money = Money.newBuilder().setAmount(10).build();
                responseObserver.onNext(money);
                log.info("money sent :{},{}",money, Context.current().isCancelled());
                AccountRespository.deductAccount(accountNumber, 10);
                Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
            }
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).getCause());
        }
    }


}
